home *** CD-ROM | disk | FTP | other *** search
/ TOS Silver 2000 / TOS Silver 2000.iso / programm / MM2_DEV / S / MOS / RANDOMGE.I < prev    next >
Encoding:
Modula Implementation  |  1991-05-20  |  3.2 KB  |  110 lines

  1.  
  2. IMPLEMENTATION MODULE RandomGen;        (*$ c- *)
  3. (*$R-,S-,Y+*)
  4.  
  5. (* Zufallszahlengenerator
  6.    (Knuth, Art of Computer Programming Vol.2, 2nd Ed., pp.16/102)
  7.  
  8.    jm 15.6.87
  9.    
  10.    tt 25.9.88: RandomCard (x,MaxCard) ergibt keinen Überlauf mehr.
  11.    tt 14.3.90: RandomCard berechnet nun direkt aus Rnd() mit Int-Arithm.
  12.                statt über Random() mit Reals.
  13.    tt 20.5.91: Rnd() zerstört nicht mehr D3
  14. *)
  15.  
  16. FROM SYSTEM IMPORT ASSEMBLER, CompilerVersion;
  17.  
  18. CONST  a = 1664525;     (* Knuth S.102 Zeile 26 *)
  19.        c = 117;         (* teilerfremd mit 2^32 für max. Periode 2^32 *)
  20.   maxRnd = 4294967296.; (* 2^32 für Normierung auf [0..1) *)
  21.  
  22. VAR    x: LONGCARD;     (* letzte erzeugte Zufallszahl *)
  23.  
  24. (*$ l- *)
  25. PROCEDURE Randomize (seed: LONGCARD);
  26.   BEGIN
  27.     ASSEMBLER
  28.       move.l    -(a3),d0
  29.       beq       rnd2
  30.       move.l    d0,x
  31.       rts
  32.     rnd2
  33.       move      #17,-(a7)
  34.       trap      #14
  35.       eor.l     d0,x
  36.       trap      #14
  37.       addq.l    #2,a7
  38.       lsl.l     #8,d0
  39.       eor.l     d0,x
  40.     END
  41.   END Randomize;
  42.   
  43. (*$ l- *)
  44. PROCEDURE Rnd (): LONGCARD;
  45.   BEGIN
  46.     ASSEMBLER
  47.       
  48.       ; berechne a * x: drei Teilprodukte bilden
  49.       ; (x.high * a.high brauchen wir nicht, fällt dem MOD zum Opfer)
  50.       
  51.       move.l    x,d0    ;x.low
  52.       move.l    d0,d1   ;x.low
  53.       move.l    d0,d2
  54.       swap      d2      ;x.high
  55.       move.l    d3,-(a7)
  56.       move.l    #a,d3
  57.       mulu      d3,d0   ;al * xl
  58.       mulu      d3,d2   ;al * xh
  59.       swap      d3
  60.       mulu      d3,d1   ;ah * xl
  61.       move.l    (a7)+,d3
  62.       
  63.       ; Teilprodukte aufaddieren
  64.       
  65.       swap      d1
  66.       clr.w     d1
  67.       swap      d2
  68.       clr.w     d2
  69.       add.l     d1,d0
  70.       add.l     d2,d0
  71.       
  72.       ; nun noch c addieren und Ergebnis abliefern
  73.       
  74.       addi.l    #c,d0
  75.       move.l    d0,x
  76.       move.l    d0,(A3)+
  77.     END
  78.   END Rnd;
  79.   
  80. (*$ l+ *)
  81. PROCEDURE Random (): LONGREAL;
  82.   BEGIN
  83.     (*$? CompilerVersion = 3: RETURN float (Rnd()) / maxRnd *)
  84.     (*$? CompilerVersion > 3: RETURN Lfloat (Rnd()) / maxRnd *)
  85.   END Random;
  86.  
  87. (*$ l+ *)
  88. PROCEDURE RandomCard (min, max: CARDINAL): CARDINAL;
  89.   (* liefert Pseudo-Zufallszahl  min <= RandomCard () <= max *)
  90.   VAR siz: LONGCARD;
  91.   BEGIN
  92.     ASSEMBLER
  93.         MOVEQ   #0,D0
  94.         MOVEQ   #0,D1
  95.         MOVE    max(A6),D0
  96.         ADDQ.L  #1,D0
  97.         MOVE    min(A6),D1
  98.         SUB.L   D1,D0
  99.         MOVE.L  D0,siz(A6)
  100.     END;
  101.     RETURN (* min + SHORT (LONGCARD (TRUNC (Random () * Lfloat (siz)))) *)
  102.            min + SHORT (Rnd () MOD siz)
  103.   END RandomCard;
  104.  
  105. BEGIN
  106.   Randomize (0L)
  107. END RandomGen.
  108. ə
  109. (* $FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$00000341$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082$FFF8B082Ç$00000636T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$00000581$00000646$00000636$0000063E$00000357$FFEDF490$0000040B$FFEDF490$000003C8$0000037A$00000101$000001A4$00000184$FFF16614$000001A2$00000593ÉÇÇ*)
  110.